package com.gdpu.liou.symphonyserver.controller;
import java.util.Date;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gdpu.liou.symphonyserver.common.aspect.WebLog;
import com.gdpu.liou.symphonyserver.entity.respose.Response;
import com.gdpu.liou.symphonyserver.entity.Song;
import com.gdpu.liou.symphonyserver.entity.respose.ResponseCode;
import com.gdpu.liou.symphonyserver.service.SongService;
import com.gdpu.liou.symphonyserver.common.utils.Consts;
import com.gdpu.liou.symphonyserver.common.utils.PagingUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * @author liuyx
 */
@RestController
@RequestMapping("/song")
@Slf4j
public class SongController {
    @Autowired
    private SongService songService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 添加歌曲
     */

    @RequestMapping(value = "/insertSong", method = RequestMethod.POST)
    public Object addSong(HttpServletRequest request, @RequestParam("pic") MultipartFile pic,@RequestParam("file") MultipartFile file) throws IOException {
        JSONObject jsonObject = new JSONObject();

      try {
          songService.uploadFile(request,pic,file);
          jsonObject.put(Consts.CODE, 1);
          jsonObject.put(Consts.MSG, "添加成功");
      }catch (Exception e){
          jsonObject.put(Consts.CODE, 0);
          jsonObject.put(Consts.MSG, e.getMessage());
      }finally {
          return jsonObject;
      }



    }

    /**
     * 删除歌手
     */

    @RequestMapping(value = "/deleteSong", method = RequestMethod.GET)
    public Object deleteSong(String id) {
        JSONObject jsonObject = new JSONObject();
        //删除歌手
        boolean flag = songService.deleteSong(Integer.parseInt(id));
        //删除成功
        if (flag) {
            jsonObject.put(Consts.CODE, 1);
            jsonObject.put(Consts.MSG, "删除成功");
            return jsonObject;
        }
        //删除失败
        jsonObject.put(Consts.CODE, 0);
        jsonObject.put(Consts.MSG, "删除失败");
        return jsonObject;
    }

    /**
     * 修改歌曲
     */

    @RequestMapping(value = "/updateSong", method = RequestMethod.POST)
    public Object updateSong(HttpServletRequest request) {
        JSONObject jsonObject = new JSONObject();
        try {
            //修改歌手
            songService.updateSong(request);
            //修改成功
            jsonObject.put(Consts.CODE, 1);
            jsonObject.put(Consts.MSG, "修改成功");

        }catch (Exception e){
            //修改失败
            jsonObject.put(Consts.CODE, 0);
            jsonObject.put(Consts.MSG, "修改失败");
        }
       finally {
            return jsonObject;
        }

    }


    /**
     * 更新歌曲图片
     */

    @RequestMapping(value = "/updateSongPic", method = RequestMethod.POST)
    public Object updateSingerPic(@RequestParam("file") MultipartFile file, @RequestParam("id") int id) throws IOException {
        JSONObject jsonObject = new JSONObject();
        try {
            songService.updataSongPic(id,file);
            jsonObject.put(Consts.CODE, 1);
            jsonObject.put(Consts.MSG, "修改成功");
        } catch (IOException e) {
            jsonObject.put(Consts.CODE, 0);
            jsonObject.put(Consts.MSG, e.getMessage());
        } finally {
            return jsonObject;
        }

    }

    /**
     * 分页查询歌手的所有歌曲：根据歌手id
     */

    @RequestMapping(value = "/pagingQuerySong", method = RequestMethod.GET)
    public PagingUtil pagingSongsBySingerId(@RequestParam(required = false) Integer singerId,
                                            @RequestParam(required = false) Integer currentPage,
                                            @RequestParam(required = false) String word,
                                            @RequestParam(required = false) Integer pageSize) {
        if (currentPage == null) {
            currentPage = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        return songService.songOfSingerId(singerId, currentPage, word, pageSize);
    }


    /**
     * 查询歌手的所有歌曲：根据歌手id
     */

    @RequestMapping(value = "/selectSongsBySingerId", method = RequestMethod.GET)
    public Response selectSongsBySingerId(@RequestParam Integer singerId) {
        List<Song> songs = songService.selectSongsBySingerId(singerId);
        if (CollectionUtils.isEmpty(songs)) {
            return new Response<>(Collections.emptyList());
        }
        return new Response<>(songs, songs.size());
    }


    /**
     * 查询歌曲：根据歌曲id
     */

    @GetMapping(value = "/detail")
    public Song songOfSongId(Integer songId) {
        return songService.songOfSongId(songId);
    }


    /**
     * 根据歌手-歌曲模糊查询歌曲
     *
     * @param keyword 关键字
     * @param limit   查询数据最大条数
     */

    @RequestMapping(value = "/likeSongByKeyword", method = RequestMethod.GET)
    public Object likeSongByKeyword(@RequestParam("keyword") String keyword,
                                    @RequestParam(value = "limit", required = false) Integer limit) {

        return songService.likeSongSingerByKeyword(keyword, limit);
    }


    @RequestMapping(value = "/likeSongNameByKeyword", method = RequestMethod.GET)
    public Response likeSongByKeyword(@RequestParam("keyword") String keyword) {
        List<Song> songs = songService.likeSongByKeyword(keyword);
        if (CollectionUtils.isEmpty(songs)) {
            return new Response<>();
        }
        return new Response<List<Song>>(songs, songs.size());
    }


    /**
     * 查询用户最近播放列表
     */

    @RequestMapping(value = "/recentlySongList", method = RequestMethod.GET)
    public Object recentlySongList(HttpServletRequest request) {
        String consumerId = request.getParameter("consumerId");
        if (StringUtils.isEmpty(consumerId)) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(Consts.CODE, 0);
            jsonObject.put(Consts.MSG, "用户未登录请先登录！");
            return jsonObject;
        }
        return songService.recentlySongList(Integer.valueOf(consumerId));
    }

    /**
     * 更新用户最近播放歌曲
     */

    @RequestMapping(value = "/insertRecentlySong", method = RequestMethod.GET)
    public Object insertRecentlySong(HttpServletRequest request) {
        String consumerId = request.getParameter("consumerId");
        String songId = request.getParameter("songId");
        if (consumerId != null && songId != null) {
            boolean flag = songService.replaceRecentlySong(Integer.parseInt(consumerId), Integer.parseInt(songId));
            if (flag) {
                log.info("更新用户最近播放歌曲成功，consumerId:{}-songId:{}", consumerId, songId);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(Consts.CODE, 1);
                return jsonObject;
            }
        }
        log.warn("更新用户最近播放歌曲失败，consumerId:{}-songId:{}", consumerId, songId);
        return null;
    }


    @RequestMapping(value = "/selectSongSelected", method = RequestMethod.GET)
    public Response selectSongSelected() {
        return new Response(200, "成功", 123, 1);
    }

    /**
     * 歌曲排行榜（可分租）
     *
     * @param number 排行榜top数
     * @param group  每组歌曲数
     * @return 返回歌曲数组列表
     */
    @WebLog(description = "歌曲排行榜")
    @RequestMapping(value = "/songRankingList", method = RequestMethod.GET)
    public Response songRankingList(@RequestParam int number, @RequestParam(defaultValue = "0") int group) {
        return songService.songRankingList(number, group);
    }


    /**
     * 每日推荐-歌曲
     * 从数据库中随机抽取30条歌曲并添加到缓存中，有效期一天
     */
    @WebLog(description = "每日推荐-歌曲")
    @RequestMapping(value = "/randomSong", method = RequestMethod.GET)
    public Response randomSong(@RequestParam(value = "isCache", required = false) Integer isCache) {
        try {
            // 流程控制 - 参数 isCache == 1 代表查询缓存中的数据
            if (Objects.equals(isCache, 1)) {
                // 数据查询 - 调用查询Redis缓存的歌曲列表
                List<Song> cacheSongs = songService.randomSongByCache();
                // 如果缓存为空 调用查询MySQL数据库 并将歌曲列表存入缓存
                if (!Optional.ofNullable(cacheSongs).isPresent()) {
                    List<Song> songs = songService.randomSong();
                    ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
                    // 添加Redis缓存有效期一天 格式为Json字符串
                    String songsJson = JSON.toJSONString(songs);
                    operations.set("randomSong", songsJson, 1, TimeUnit.DAYS);
                    return new Response<>(songs, songs.size());
                }
                return new Response<>(cacheSongs);
            }
            // 流程控制 直接查询MySQL数据库
            List<Song> songs = songService.randomSong();
            if (CollectionUtils.isEmpty(songs)) {
                //  EMPTY(200, "data is empty"),
                return new Response<>(ResponseCode.EMPTY);
            }
            return new Response<>(songs, songs.size());
        } catch (Exception e) {
            log.error("请求每日推荐-歌曲失败", e);
            return new Response<>(500, "系统内部错误 - randomSong()：请求每日推荐-歌曲列表失败");
        }
    }


    /**
     * 查询用户收藏歌曲列表
     */

    @RequestMapping(value = "/selectCollectSong", method = RequestMethod.GET)
    public Response selectCollectSong(@RequestParam("consumerId") Long consumerId) {
        try {
            List<Song> songs = songService.selectCollectSong(consumerId);
            return new Response(songs);
        } catch (Exception e) {
            log.error("请求-selectCollectSong-查询用户收藏歌曲列表失败", e);
            return new Response(0, "系统内部错误，请求查询用户收藏歌曲列表失败");
        }
    }

    /**
     * 查询用户收藏歌曲列表id
     */

    @RequestMapping(value = "/selectCollectSongId", method = RequestMethod.GET)
    public Response selectCollectSongId(@RequestParam("consumerId") Long consumerId) {
        try {
            List<Integer> integers = songService.selectCollectSongId(consumerId);
            if (CollectionUtils.isEmpty(integers)) {
                return new Response<>(Collections.emptyList());
            }
            return new Response(integers);
        } catch (Exception e) {
            log.error("请求-selectCollectSongId-查询用户收藏歌曲列表id", e);
            return new Response(500, "系统内部错误，请求查询用户收藏歌曲列表失败");
        }
    }

    /**
     * 收藏歌曲
     */

    @RequestMapping(value = "/insertCollectSong", method = RequestMethod.GET)
    public Response insertCollectSong(@RequestParam("consumerId") Integer consumerId, @RequestParam Integer songId) {
        try {
            boolean insertCollectSong = songService.insertCollectSong(consumerId, songId);
            return new Response<>(insertCollectSong);
        } catch (Exception e) {
            log.error("请求-insertCollectSong-收藏歌曲失败", e);
            return new Response(500, "系统内部错误，请求收藏歌曲失败");
        }
    }


    /**
     * 查询歌单的歌曲列表
     */

    @RequestMapping(value = "/selectSongsOfPlaylist", method = RequestMethod.GET)
    public Response selectSongsOfPlaylist(@RequestParam("playlistId") Long playlistId) {
        try {
            List<Song> songs = songService.selectSongsOfPlaylist(playlistId);
            if (CollectionUtils.isEmpty(songs)) {
                return new Response<>();
            }
            return new Response<List<Song>>(songs, songs.size());
        } catch (Exception e) {
            log.error("请求查询歌单的歌曲列表失败", e);
            return new Response<>(ResponseCode.SERVER_ERROR);
        }
    }

    /**
     * 查询歌曲播放排行榜
     */

    @RequestMapping(value = "/selectRankingOfSong", method = RequestMethod.GET)
    public Response selectRankingOfSong(@RequestParam(value = "limit", required = false) Integer limit) {
        try {
            List<Song> songs = songService.selectRankingOfSong(limit);
            if (CollectionUtils.isEmpty(songs)) {
                return new Response<>();
            }
            return new Response<List<Song>>(songs, songs.size());
        } catch (Exception e) {
            log.error("请求查询歌曲播放排行榜失败", e);
            return new Response<>(ResponseCode.SERVER_ERROR);
        }
    }

}
